load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load(
    "//bazel/config:configs.bzl",
    "allocator",
    "asan",
    "build_enterprise",
    "build_grpc",
    "build_otel",
    "compiler_type",
    "dbg",
    "dbg_level",
    "debug_symbols",
    "detect_odr_violations",
    "developer_dir",
    "disable_warnings_as_errors",
    "dwarf_version",
    "fsan",
    "gcov",
    "http_client",
    "js_engine",
    "libunwind",
    "linker",
    "linkstatic",
    "lsan",
    "msan",
    "opt",
    "pgo_profile",
    "release",
    "separate_debug",
    "server_js",
    "shared_archive",
    "spider_monkey_dbg",
    "ssl",
    "streams_release_build",
    "thin_lto",
    "tsan",
    "ubsan",
    "use_disable_ref_track",
    "use_gdbserver",
    "use_glibcxx_debug",
    "use_libcxx",
    "use_lldbserver",
    "use_ocsp_stapling",
    "use_wait_for_debugger",
    "use_wiredtiger",
    "visibility_support",
)

package(default_visibility = ["//visibility:public"])

# Expose script for external usage through bazel.
exports_files([
    "generate_config_header.py",
])

# --------------------------------------
# Compiler types
# --------------------------------------

compiler_type(
    name = "compiler_type",
    build_setting_default = "gcc",
)

config_setting(
    name = "compiler_type_clang",
    flag_values = {
        "//bazel/config:compiler_type": "clang",
    },
)

config_setting(
    name = "compiler_type_gcc",
    flag_values = {
        "//bazel/config:compiler_type": "gcc",
    },
)

config_setting(
    name = "compiler_type_msvc",
    flag_values = {
        "//bazel/config:compiler_type": "msvc",
    },
)

selects.config_setting_group(
    name = "gcc_or_clang",
    match_any = [
        ":compiler_type_gcc",
        ":compiler_type_clang",
    ],
)

selects.config_setting_group(
    name = "linux_gcc_or_clang",
    match_all = [
        "@platforms//os:linux",
        ":gcc_or_clang",
    ],
)

config_setting(
    name = "linux_gcc",
    constraint_values = [
        "@platforms//os:linux",
    ],
    flag_values = {
        "//bazel/config:compiler_type": "gcc",
    },
)

config_setting(
    name = "suse15_gcc",
    constraint_values = [
        "@platforms//os:linux",
        "//bazel/platforms:suse15",
    ],
    flag_values = {
        "//bazel/config:compiler_type": "gcc",
    },
)

selects.config_setting_group(
    name = "suse15_gcc_linkstatic",
    match_all = [
        "@platforms//os:linux",
        "//bazel/platforms:suse15",
        ":compiler_type_gcc",
        ":linkstatic_enabled",
    ],
)

selects.config_setting_group(
    name = "linux_clang",
    match_all = [
        "@platforms//os:linux",
        ":compiler_type_clang",
    ],
)

selects.config_setting_group(
    name = "linux_clang_linkstatic",
    match_all = [
        "@platforms//os:linux",
        ":compiler_type_clang",
        ":linkstatic_enabled",
    ],
)

selects.config_setting_group(
    name = "macos_gcc_or_clang",
    match_all = [
        "@platforms//os:macos",
        ":gcc_or_clang",
    ],
)

selects.config_setting_group(
    name = "gcc_opt",
    match_all = [
        ":compiler_type_gcc",
        ":opt_any",
    ],
)

selects.config_setting_group(
    name = "msvc_opt",
    match_all = [
        ":compiler_type_msvc",
        ":opt_any",
    ],
)

# --------------------------------------
# Architecture + OS combinations
# --------------------------------------

config_setting(
    name = "linux_aarch64",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:aarch64",
    ],
)

config_setting(
    name = "linux_x86_64",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
)

config_setting(
    name = "linux_ppc64le",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:ppc",
    ],
)

config_setting(
    name = "linux_s390x",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:s390x",
    ],
)

config_setting(
    name = "windows_x86_64",
    constraint_values = [
        "@platforms//os:windows",
        "@platforms//cpu:x86_64",
    ],
)

config_setting(
    name = "macos_x86_64",
    constraint_values = [
        "@platforms//os:macos",
        "@platforms//cpu:x86_64",
    ],
)

config_setting(
    name = "macos_aarch64",
    constraint_values = [
        "@platforms//os:macos",
        "@platforms//cpu:aarch64",
    ],
)

selects.config_setting_group(
    name = "not_windows",
    match_any = [
        "@platforms//os:macos",
        "@platforms//os:linux",
    ],
)

selects.config_setting_group(
    name = "not_linux",
    match_any = [
        "@platforms//os:macos",
        "@platforms//os:windows",
    ],
)

selects.config_setting_group(
    name = "not_macos",
    match_any = [
        "@platforms//os:linux",
        "@platforms//os:windows",
    ],
)

selects.config_setting_group(
    name = "not_s390x",
    match_any = [
        "@platforms//cpu:aarch64",
        "@platforms//cpu:x86_64",
        "@platforms//cpu:ppc",
    ],
)

selects.config_setting_group(
    name = "posix",
    match_any = [
        "@platforms//os:macos",
        "@platforms//os:linux",
    ],
)

selects.config_setting_group(
    name = "gcc_x86_64",
    match_all = [
        ":compiler_type_gcc",
        "@platforms//cpu:x86_64",
    ],
)

selects.config_setting_group(
    name = "gcc_aarch64",
    match_all = [
        ":compiler_type_gcc",
        "@platforms//cpu:aarch64",
    ],
)

# ==========
# opt
# ==========

opt(
    name = "opt",
    build_setting_default = "auto",
)

config_setting(
    name = "_opt_on",
    flag_values = {
        "//bazel/config:opt": "on",
    },
)

config_setting(
    name = "_opt_off",
    flag_values = {
        "//bazel/config:opt": "off",
    },
)

config_setting(
    name = "_opt_auto",
    flag_values = {
        "//bazel/config:opt": "auto",
    },
)

selects.config_setting_group(
    name = "_opt_on_set_by_auto",
    match_all = [
        ":_opt_auto",
        ":dbg_disabled",
    ],
)

selects.config_setting_group(
    name = "_opt_off_set_by_auto",
    match_all = [
        ":_opt_auto",
        ":dbg_enabled",
    ],
)

# opt=on || (opt=auto && !dbg)
selects.config_setting_group(
    name = "opt_on",
    match_any = [
        ":_opt_on_set_by_auto",
        ":_opt_on",
    ],
)

# opt=off || (opt=auto && dbg)
selects.config_setting_group(
    name = "opt_off",
    match_any = [
        ":_opt_off_set_by_auto",
        ":_opt_off",
    ],
)

config_setting(
    name = "opt_size",
    flag_values = {
        "//bazel/config:opt": "size",
    },
)

config_setting(
    name = "opt_debug",
    flag_values = {
        "//bazel/config:opt": "debug",
    },
)

selects.config_setting_group(
    name = "opt_any",
    match_any = [
        ":opt_on",
        ":opt_size",
        ":opt_debug",
    ],
)

selects.config_setting_group(
    name = "macos_opt_off",
    match_all = [
        "@platforms//os:macos",
        ":opt_off",
    ],
)

# ==========
# dbg
# ==========

dbg(
    name = "dbg",
    build_setting_default = True,
)

config_setting(
    name = "dbg_enabled",
    flag_values = {
        "//bazel/config:dbg": "True",
    },
)

config_setting(
    name = "dbg_disabled",
    flag_values = {
        "//bazel/config:dbg": "False",
    },
)

# ==========
# dbg_level
# ==========

dbg_level(
    name = "dbg_level",
    build_setting_default = "2",
)

config_setting(
    name = "dbg_level_0",
    flag_values = {
        "//bazel/config:dbg_level": "0",
    },
)

config_setting(
    name = "dbg_level_1",
    flag_values = {
        "//bazel/config:dbg_level": "1",
    },
)

config_setting(
    name = "dbg_level_2",
    flag_values = {
        "//bazel/config:dbg_level": "2",
    },
)

config_setting(
    name = "dbg_level_3",
    flag_values = {
        "//bazel/config:dbg_level": "3",
    },
)

selects.config_setting_group(
    name = "gcc_or_clang_dbg_level_0",
    match_all = [
        ":gcc_or_clang",
        ":dbg_level_0",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_dbg_level_1",
    match_all = [
        ":gcc_or_clang",
        ":dbg_level_1",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_dbg_level_2",
    match_all = [
        ":gcc_or_clang",
        ":dbg_level_2",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_dbg_level_3",
    match_all = [
        ":gcc_or_clang",
        ":dbg_level_3",
    ],
)

# =========
# debug symbols
# =========

debug_symbols(
    name = "debug_symbols",
    build_setting_default = True,
)

config_setting(
    name = "debug_symbols_enabled",
    flag_values = {
        "//bazel/config:debug_symbols": "True",
    },
)

config_setting(
    name = "debug_symbols_disabled",
    flag_values = {
        "//bazel/config:debug_symbols": "False",
    },
)

selects.config_setting_group(
    name = "not_windows_debug_symbols_disabled",
    match_all = [
        ":not_windows",
        ":debug_symbols_disabled",
    ],
)

# We can't disable windows symbol generation with a flag, we can only omit the flags that generate them
selects.config_setting_group(
    name = "windows_debug_symbols_enabled",
    match_all = [
        "@platforms//os:windows",
        ":debug_symbols_enabled",
    ],
)

# ==========
# release
# ==========

release(
    name = "release",
    build_setting_default = False,
)

config_setting(
    name = "release_enabled",
    flag_values = {
        "//bazel/config:release": "True",
    },
)

config_setting(
    name = "release_disabled",
    flag_values = {
        "//bazel/config:release": "False",
    },
)

selects.config_setting_group(
    name = "linux_dbg",
    match_all = [
        "@platforms//os:linux",
        ":dbg_enabled",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_opt_off",
    match_all = [
        ":gcc_or_clang",
        ":opt_off",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_opt_on",
    match_all = [
        ":gcc_or_clang",
        ":opt_on",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_opt_any",
    match_all = [
        ":gcc_or_clang",
        ":opt_any",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_opt_size",
    match_all = [
        ":gcc_or_clang",
        ":opt_size",
    ],
)

selects.config_setting_group(
    name = "gcc_or_clang_opt_debug",
    match_all = [
        ":gcc_or_clang",
        ":opt_debug",
    ],
)

selects.config_setting_group(
    name = "linux_release",
    match_all = [
        "@platforms//os:linux",
        ":release_enabled",
    ],
)

selects.config_setting_group(
    name = "windows_dbg_enabled",
    match_all = [
        "@platforms//os:windows",
        ":dbg_enabled",
    ],
)

selects.config_setting_group(
    name = "windows_dbg_disabled",
    match_all = [
        "@platforms//os:windows",
        ":dbg_disabled",
    ],
)

selects.config_setting_group(
    name = "windows_opt_off",
    match_all = [
        "@platforms//os:windows",
        ":opt_off",
    ],
)

selects.config_setting_group(
    name = "windows_opt_on",
    match_all = [
        "@platforms//os:windows",
        ":opt_on",
    ],
)

selects.config_setting_group(
    name = "windows_opt_any",
    match_all = [
        "@platforms//os:windows",
        ":opt_any",
    ],
)

selects.config_setting_group(
    name = "windows_opt_size",
    match_all = [
        "@platforms//os:windows",
        ":opt_size",
    ],
)

selects.config_setting_group(
    name = "windows_opt_debug",
    match_all = [
        "@platforms//os:windows",
        ":opt_debug",
    ],
)

selects.config_setting_group(
    name = "windows_opt_off_dbg_enabled",
    match_all = [
        "@platforms//os:windows",
        ":opt_off",
        ":dbg_enabled",
    ],
)

# --------------------------------------
# linker options
# --------------------------------------

linker(
    name = "linker",
    build_setting_default = "auto",
)

# Underscored settings are for flagging configuration errors and for evaluating auto.
# Use :linker_gold & linker_lld to check the final evaluated linker.
config_setting(
    name = "_linker_auto",
    flag_values = {
        "//bazel/config:linker": "auto",
    },
)

config_setting(
    name = "_linker_gold",
    flag_values = {
        "//bazel/config:linker": "gold",
    },
)

config_setting(
    name = "_linker_lld",
    flag_values = {
        "//bazel/config:linker": "lld",
    },
)

selects.config_setting_group(
    name = "_linker_gold_set_by_auto",
    match_all = [
        ":_linker_auto",
        "@platforms//cpu:s390x",
        "@platforms//os:linux",
    ],
)

selects.config_setting_group(
    name = "_linker_lld_set_by_auto",
    match_all = [
        ":_linker_auto",
        ":not_s390x",
        "@platforms//os:linux",
    ],
)

# Final setting intended for external use.
#   linker == gold || (linker == auto && cpu == s390x)
selects.config_setting_group(
    name = "linker_gold",
    match_any = [
        ":_linker_gold_set_by_auto",
        ":_linker_gold",
    ],
)

# Final setting intended for external use.
#   linker == lld || (linker == auto && cpu == not_s390x)
selects.config_setting_group(
    name = "linker_lld",
    match_any = [
        ":_linker_lld_set_by_auto",
        ":_linker_lld",
    ],
)

selects.config_setting_group(
    name = "linker_lld_valid_settings",
    match_all = [
        ":linker_lld",
        ":not_s390x",
        ":not_macos",
    ],
)

selects.config_setting_group(
    name = "linker_default",
    match_all = [
        ":_linker_auto",
        ":not_linux",
    ],
)

# --------------------------------------
# libunwind options
# --------------------------------------

libunwind(
    name = "libunwind",
    build_setting_default = "auto",
)

# Underscored settings are for flagging configuration errors and for evaluating auto.
# Use :libunwind_enabled to check the final result of whether or not it's enabled.
config_setting(
    name = "_libunwind_on",
    flag_values = {
        "//bazel/config:libunwind": "on",
    },
)

config_setting(
    name = "_libunwind_off",
    flag_values = {
        "//bazel/config:libunwind": "off",
    },
)

config_setting(
    name = "_libunwind_auto",
    flag_values = {
        "//bazel/config:libunwind": "auto",
    },
)

selects.config_setting_group(
    name = "_libunwind_enabled_by_auto",
    match_all = [
        ":_libunwind_auto",
        "@platforms//os:linux",
    ],
)

selects.config_setting_group(
    name = "_libunwind_disabled_by_auto",
    match_all = [
        ":_libunwind_auto",
        ":not_linux",
    ],
)

selects.config_setting_group(
    name = "_libunwind_enabled_by_on",
    match_all = [
        ":_libunwind_on",
        "@platforms//os:linux",
    ],
)

# Final setting intended for external use.
#   (libunwind == on && os == linux) || (libunwind == auto && os == linux)
selects.config_setting_group(
    name = "libunwind_enabled",
    match_any = [
        ":_libunwind_enabled_by_on",
        ":_libunwind_enabled_by_auto",
    ],
)

selects.config_setting_group(
    name = "libunwind_disabled",
    match_any = [
        ":_libunwind_off",
        ":_libunwind_disabled_by_auto",
    ],
)

selects.config_setting_group(
    name = "libunwind_disabled_linux",
    match_all = [
        ":libunwind_disabled",
        "@platforms//os:linux",
    ],
)

# --------------------------------------
# gdbserver options
# --------------------------------------

use_gdbserver(
    name = "use_gdbserver",
    build_setting_default = False,
)

config_setting(
    name = "use_gdbserver_enabled",
    flag_values = {
        "//bazel/config:use_gdbserver": "True",
    },
)

# --------------------------------------
# Spider Monkey Debug options
# --------------------------------------

spider_monkey_dbg(
    name = "spider_monkey_dbg",
    build_setting_default = False,
)

config_setting(
    name = "spider_monkey_dbg_enabled",
    flag_values = {
        "//bazel/config:spider_monkey_dbg": "True",
    },
)

# --------------------------------------
# allocator options
# --------------------------------------

allocator(
    name = "allocator",
    build_setting_default = "auto",
)

config_setting(
    name = "_tcmalloc_google",
    flag_values = {
        "//bazel/config:allocator": "tcmalloc-google",
    },
)

config_setting(
    name = "_tcmalloc_gperf",
    flag_values = {
        "//bazel/config:allocator": "tcmalloc-gperf",
    },
)

config_setting(
    name = "_system_allocator",
    flag_values = {
        "//bazel/config:allocator": "system",
    },
)

config_setting(
    name = "_auto_allocator",
    flag_values = {
        "//bazel/config:allocator": "auto",
    },
)

selects.config_setting_group(
    name = "_tcmalloc_google_supported_archs",
    match_any = [
        "@platforms//cpu:aarch64",
        "@platforms//cpu:x86_64",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_google_selected_by_auto",
    match_all = [
        ":_auto_allocator",
        "@platforms//os:linux",
        ":_tcmalloc_google_supported_archs",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_gperf_auto_supported",
    match_any = [
        "@platforms//os:windows",
        "@platforms//cpu:ppc",
        "@platforms//cpu:s390x",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_gperf_supported_os",
    match_any = [
        "@platforms//os:windows",
        "@platforms//os:linux",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_gperf_selected_by_auto",
    match_all = [
        ":_auto_allocator",
        ":_tcmalloc_gperf_auto_supported",
    ],
)

selects.config_setting_group(
    name = "_system_allocator_enabled_by_auto",
    match_all = [
        ":_auto_allocator",
        "@platforms//os:macos",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_google_selected",
    match_any = [
        ":_tcmalloc_google_selected_by_auto",
        ":_tcmalloc_google",
    ],
)

selects.config_setting_group(
    name = "_tcmalloc_gperf_selected",
    match_any = [
        ":_tcmalloc_gperf_selected_by_auto",
        ":_tcmalloc_gperf",
    ],
)

selects.config_setting_group(
    name = "system_allocator_enabled",
    match_any = [
        ":_system_allocator_enabled_by_auto",
        ":_system_allocator",
    ],
)

selects.config_setting_group(
    name = "tcmalloc_google_enabled",
    match_all = [
        ":_tcmalloc_google_selected",
        "@platforms//os:linux",
        ":_tcmalloc_google_supported_archs",
    ],
)

selects.config_setting_group(
    name = "tcmalloc_gperf_enabled",
    match_all = [
        ":_tcmalloc_gperf_selected",
        ":_tcmalloc_gperf_supported_os",
    ],
)

selects.config_setting_group(
    name = "non_system_allocator_enabled",
    match_any = [
        ":tcmalloc_google_enabled",
        ":tcmalloc_gperf_enabled",
    ],
)

selects.config_setting_group(
    name = "non_system_allocator_enabled_and_debug",
    match_all = [
        ":non_system_allocator_enabled",
        ":dbg_enabled",
    ],
)

# --------------------------------------
# gdbserver options
# --------------------------------------

use_lldbserver(
    name = "use_lldbserver",
    build_setting_default = False,
)

config_setting(
    name = "use_lldbserver_enabled",
    flag_values = {
        "//bazel/config:use_lldbserver": "True",
    },
)

# --------------------------------------
# wait-for-debugger options
# --------------------------------------

use_wait_for_debugger(
    name = "use_wait_for_debugger",
    build_setting_default = False,
)

config_setting(
    name = "use_wait_for_debugger_enabled",
    flag_values = {
        "//bazel/config:use_wait_for_debugger": "True",
    },
)

# --------------------------------------
# ocsp-stapling options
# --------------------------------------

use_ocsp_stapling(
    name = "use_ocsp_stapling",
    build_setting_default = False,
)

config_setting(
    name = "use_ocsp_stapling_enabled",
    flag_values = {
        "//bazel/config:use_ocsp_stapling": "True",
    },
)

# --------------------------------------
# disable-ref-track options
# --------------------------------------

use_disable_ref_track(
    name = "use_disable_ref_track",
    build_setting_default = False,
)

config_setting(
    name = "use_disable_ref_track_enabled",
    flag_values = {
        "//bazel/config:use_disable_ref_track": "True",
    },
)

config_setting(
    name = "use_disable_ref_track_disabled",
    flag_values = {
        "//bazel/config:use_disable_ref_track": "False",
    },
)

selects.config_setting_group(
    name = "selected_disable_ref_track",
    match_any = [
        ":use_disable_ref_track_disabled",
        ":release_enabled",
    ],
)

# --------------------------------------
# wiredtiger options
# --------------------------------------

use_wiredtiger(
    name = "use_wiredtiger",
    build_setting_default = True,
)

config_setting(
    name = "use_wiredtiger_enabled",
    flag_values = {
        "//bazel/config:use_wiredtiger": "True",
    },
)

# --------------------------------------
# glibcxx debug options
# --------------------------------------

use_glibcxx_debug(
    name = "use_glibcxx_debug",
    build_setting_default = False,
)

config_setting(
    name = "use_glibcxx_debug_enabled",
    flag_values = {
        "//bazel/config:use_glibcxx_debug": "True",
    },
)

config_setting(
    name = "use_glibcxx_debug_disabled",
    flag_values = {
        "//bazel/config:use_glibcxx_debug": "False",
    },
)

# --------------------------------------------
# ------- computed glibcxx debug flags -------

# If we are using a modern libstdc++ and this is a debug build and we control all C++
# dependencies, then turn on the debugging features in libstdc++.
selects.config_setting_group(
    name = "use_glibcxx_debug_required_settings",
    #TODO SERVER-84714 add check to ensure we are using the toolchain version of C++ libs
    match_all = [
        ":use_glibcxx_debug_enabled",
        ":dbg_enabled",
        ":use_libcxx_disabled",
    ],
)

# --------------------------------------
# libc++ options
# --------------------------------------

use_libcxx(
    name = "use_libcxx",
    build_setting_default = False,
)

# TODO SERVER-85340 when libc++ is readded remove the macos constraint
config_setting(
    name = "use_libcxx_enabled",
    constraint_values = [
        "@platforms//os:macos",
    ],
    flag_values = {
        "//bazel/config:use_libcxx": "True",
    },
)

config_setting(
    name = "use_libcxx_disabled",
    flag_values = {
        "//bazel/config:use_libcxx": "False",
    },
)

# --------------------------------------------
# ----------- computed libc++ flags ----------
selects.config_setting_group(
    name = "use_libcxx_required_settings",
    match_all = [
        ":use_libcxx_enabled",
        ":compiler_type_clang",
    ],
)

# --------------------------------------
# grpc options
# --------------------------------------

build_grpc(
    name = "build_grpc",
    build_setting_default = False,
)

config_setting(
    name = "build_grpc_enabled",
    constraint_values = [
        "@platforms//os:linux",
    ],
    flag_values = {
        "//bazel/config:build_grpc": "True",
    },
)

# --------------------------------------
# otel options
# --------------------------------------

build_otel(
    name = "build_otel",
    build_setting_default = False,
)

config_setting(
    name = "build_otel_enabled",
    constraint_values = [
        "@platforms//os:linux",
    ],
    flag_values = {
        "//bazel/config:build_otel": "True",
    },
)

# --------------------------------------
# linkstatic options
# --------------------------------------

linkstatic(
    name = "linkstatic",
    build_setting_default = False,
)

config_setting(
    name = "linkstatic_enabled",
    flag_values = {
        "//bazel/config:linkstatic": "True",
    },
)

config_setting(
    name = "linkstatic_disabled",
    flag_values = {
        "//bazel/config:linkstatic": "False",
    },
)

selects.config_setting_group(
    name = "linkdynamic_required_settings",
    match_all = [
        ":linkstatic_disabled",
        ":not_windows",
    ],
)

selects.config_setting_group(
    name = "linkdynamic_not_shared_archive",
    match_all = [
        ":linkstatic_disabled",
        ":shared_archive_disabled",
    ],
)

selects.config_setting_group(
    name = "linkstatic_enabled_macos",
    match_all = [
        ":linkstatic_enabled",
        "@platforms//os:macos",
    ],
)

selects.config_setting_group(
    name = "linkstatic_enabled_linux",
    match_all = [
        ":linkstatic_enabled",
        "@platforms//os:linux",
    ],
)

# --------------------------------------
# sanitizer options
# --------------------------------------

# ------ address sanitizer --------

asan(
    name = "asan",
    build_setting_default = False,
)

config_setting(
    name = "asan_enabled",
    flag_values = {
        "//bazel/config:asan": "True",
    },
)

config_setting(
    name = "asan_disabled",
    flag_values = {
        "//bazel/config:asan": "False",
    },
)

# ------ fuzzer sanitizer --------

fsan(
    name = "fsan",
    build_setting_default = False,
)

config_setting(
    name = "fsan_enabled",
    flag_values = {
        "//bazel/config:fsan": "True",
    },
)

config_setting(
    name = "fsan_disabled",
    flag_values = {
        "//bazel/config:fsan": "False",
    },
)

# ------ leak sanitizer --------

lsan(
    name = "lsan",
    build_setting_default = False,
)

config_setting(
    name = "lsan_enabled",
    flag_values = {
        "//bazel/config:lsan": "True",
    },
)

config_setting(
    name = "lsan_disabled",
    flag_values = {
        "//bazel/config:lsan": "False",
    },
)

# ------ memory sanitizer --------

msan(
    name = "msan",
    build_setting_default = False,
)

config_setting(
    name = "msan_enabled",
    flag_values = {
        "//bazel/config:msan": "True",
    },
)

config_setting(
    name = "msan_disabled",
    flag_values = {
        "//bazel/config:msan": "False",
    },
)

# ------ thread sanitizer --------

tsan(
    name = "tsan",
    build_setting_default = False,
)

config_setting(
    name = "tsan_enabled",
    flag_values = {
        "//bazel/config:tsan": "True",
    },
)

config_setting(
    name = "tsan_disabled",
    flag_values = {
        "//bazel/config:tsan": "False",
    },
)

# ------ undefined sanitizer --------

ubsan(
    name = "ubsan",
    build_setting_default = False,
)

config_setting(
    name = "ubsan_enabled",
    flag_values = {
        "//bazel/config:ubsan": "True",
    },
)

config_setting(
    name = "ubsan_disabled",
    flag_values = {
        "//bazel/config:ubsan": "False",
    },
)

# --------------------------------------------
# ----------- computed sanitizer flags -------

selects.config_setting_group(
    name = "sanitize_build_mode",
    match_any = [
        ":opt_on",
        ":opt_debug",
    ],
)

selects.config_setting_group(
    name = "all_sanitizer_required_settings",
    match_all = [
        ":sanitize_build_mode",
        ":compiler_type_clang",
    ],
)

selects.config_setting_group(
    name = "any_enabled_sanitizer",
    match_any = [
        ":asan_enabled",
        ":fsan_enabled",
        ":msan_enabled",
        ":lsan_enabled",
        ":tsan_enabled",
        ":ubsan_enabled",
    ],
)

selects.config_setting_group(
    name = "no_enabled_sanitizer",
    match_all = [
        ":asan_disabled",
        ":fsan_disabled",
        ":msan_disabled",
        ":lsan_disabled",
        ":tsan_disabled",
        ":ubsan_disabled",
    ],
)

selects.config_setting_group(
    name = "any_sanitizer_required_setting",
    match_all = [
        ":any_enabled_sanitizer",
        ":all_sanitizer_required_settings",
    ],
)

selects.config_setting_group(
    name = "any_sanitizer_aarch64",
    match_all = [
        ":any_sanitizer_required_setting",
        "@platforms//cpu:aarch64",
    ],
)

selects.config_setting_group(
    name = "any_sanitizer_x86_64",
    match_all = [
        ":any_sanitizer_required_setting",
        "@platforms//cpu:x86_64",
    ],
)

selects.config_setting_group(
    name = "any_sanitizer_gcc",
    match_all = [
        ":any_enabled_sanitizer",
        ":compiler_type_gcc",
    ],
)

selects.config_setting_group(
    name = "sanitize_address_required_settings",
    match_all = [
        ":asan_enabled",
        ":system_allocator_enabled",
    ],
)

selects.config_setting_group(
    name = "sanitize_memory_required_settings",
    match_all = [
        ":msan_enabled",
        ":system_allocator_enabled",
    ],
)

selects.config_setting_group(
    name = "sanitize_fuzzer_required_settings",
    match_all = [":fsan_enabled"],
)

selects.config_setting_group(
    name = "sanitize_thread_required_settings",
    match_all = [
        ":tsan_enabled",
        ":libunwind_disabled",
        ":linkdynamic_required_settings",
    ],
)

selects.config_setting_group(
    name = "sanitize_undefined_without_fuzzer_settings",
    match_all = [
        ":ubsan_enabled",
        ":fsan_disabled",
    ],
)

selects.config_setting_group(
    name = "sanitize_undefined_dynamic_link_settings",
    match_all = [
        ":ubsan_enabled",
        ":linkstatic_disabled",
    ],
)

selects.config_setting_group(
    name = "sanitize_undefined_static_link_settings",
    match_all = [
        ":ubsan_enabled",
        ":linkstatic_enabled",
    ],
)

# --------------------------------------
# separate_debug options
# --------------------------------------

separate_debug(
    name = "separate_debug",
    build_setting_default = False,
)

config_setting(
    name = "separate_debug_enabled",
    flag_values = {
        "//bazel/config:separate_debug": "True",
    },
)

# --------------------------------------
# http_client options
# --------------------------------------

http_client(
    name = "http_client",
    build_setting_default = True,
)

config_setting(
    name = "http_client_enabled",
    flag_values = {
        "//bazel/config:http_client": "True",
    },
)

config_setting(
    name = "http_client_disabled",
    flag_values = {
        "//bazel/config:http_client": "False",
    },
)

# --------------------------------------
# use_tracing_profiler options
# --------------------------------------

bool_flag(
    name = "use_tracing_profiler",
    build_setting_default = False,
)

config_setting(
    name = "use_tracing_profiler_enabled",
    flag_values = {
        "//bazel/config:use_tracing_profiler": "True",
    },
)

config_setting(
    name = "use_tracing_profiler_disabled",
    flag_values = {
        "//bazel/config:use_tracing_profiler": "False",
    },
)

# --------------------------------------
# shared_archive options
# --------------------------------------

shared_archive(
    name = "shared_archive",
    build_setting_default = False,
)

config_setting(
    name = "shared_archive_enabled",
    flag_values = {
        "//bazel/config:shared_archive": "True",
    },
)

config_setting(
    name = "shared_archive_disabled",
    flag_values = {
        "//bazel/config:shared_archive": "False",
    },
)

# --------------------------------------
# detect-odr-violations options
# --------------------------------------

detect_odr_violations(
    name = "detect_odr_violations",
    build_setting_default = False,
)

config_setting(
    name = "detect_odr_violations_enabled",
    flag_values = {
        "//bazel/config:detect_odr_violations": "True",
    },
)

config_setting(
    name = "detect_odr_violations_disabled",
    flag_values = {
        "//bazel/config:detect_odr_violations": "False",
    },
)

selects.config_setting_group(
    name = "detect_odr_violations_required_settings",
    match_all = [
        ":opt_off",
        ":detect_odr_violations_enabled",
        ":linker_gold",
    ],
)

# --------------------------------------
# build_enterprise
# --------------------------------------

build_enterprise(
    name = "build_enterprise",
    build_setting_default = False,
)

config_setting(
    name = "build_enterprise_enabled",
    flag_values = {
        "//bazel/config:build_enterprise": "True",
    },
)

config_setting(
    name = "build_enterprise_disabled",
    flag_values = {
        "//bazel/config:build_enterprise": "False",
    },
)

# --------------------------------------
# stream_release_build
# --------------------------------------

streams_release_build(
    name = "streams_release_build",
    build_setting_default = False,
)

config_setting(
    name = "streams_release_build_enabled",
    flag_values = {
        "//bazel/config:streams_release_build": "True",
    },
)

config_setting(
    name = "streams_release_build_disabled",
    flag_values = {
        "//bazel/config:streams_release_build": "False",
    },
)

selects.config_setting_group(
    name = "platform_for_streaming_build",
    match_any = [
        ":linux_aarch64",
        ":linux_x86_64",
    ],
)

# The streams_release_build flag is effectively a guard to assure streams are not
# built on release builds. For non-release builds, it's not required.
selects.config_setting_group(
    name = "_streams_for_release_build",
    match_all = [
        ":release_enabled",
        ":streams_release_build_enabled",
        ":platform_for_streaming_build",
        ":ssl_enabled_linux",
    ],
)

selects.config_setting_group(
    name = "_streams_for_non_release_build",
    match_all = [
        ":release_disabled",
        ":platform_for_streaming_build",
        ":ssl_enabled_linux",
    ],
)

selects.config_setting_group(
    name = "streams_release_build_required_setting",
    match_any = [
        ":_streams_for_release_build",
        ":_streams_for_non_release_build",
    ],
)

# --------------------------------------
# stream_release_build
# --------------------------------------

visibility_support(
    name = "visibility_support",
    build_setting_default = "auto",
)

config_setting(
    name = "visibility_support_auto",
    flag_values = {
        "//bazel/config:visibility_support": "auto",
    },
)

config_setting(
    name = "visibility_support_on",
    flag_values = {
        "//bazel/config:visibility_support": "on",
    },
)

selects.config_setting_group(
    name = "visibility_support_auto_non_windows_dynamic_linking",
    match_all = [
        ":visibility_support_auto",
        ":not_windows",
        ":linkstatic_disabled",
    ],
)

selects.config_setting_group(
    name = "visibility_support_enabled_setting",
    match_any = [
        ":visibility_support_auto_non_windows_dynamic_linking",
        ":visibility_support_on",
    ],
)

selects.config_setting_group(
    name = "visibility_support_enabled_dynamic_linking_setting",
    match_all = [
        ":visibility_support_enabled_setting",
        ":linkstatic_disabled",
    ],
)

selects.config_setting_group(
    name = "visibility_support_enabled_dynamic_linking_non_windows_setting",
    match_all = [
        ":not_windows",
        ":visibility_support_enabled_setting",
        ":linkstatic_disabled",
    ],
)

# --------------------------------------
# dwarf_version
# --------------------------------------

dwarf_version(
    name = "dwarf_version",
    build_setting_default = "",
)

config_setting(
    name = "dwarf_version_4",
    flag_values = {
        "//bazel/config:dwarf_version": "4",
    },
)

config_setting(
    name = "dwarf_version_5",
    flag_values = {
        "//bazel/config:dwarf_version": "5",
    },
)

selects.config_setting_group(
    name = "dwarf_version_4_linux",
    match_all = [
        "@platforms//os:linux",
        ":dwarf_version_4",
    ],
)

selects.config_setting_group(
    name = "dwarf_version_5_linux",
    match_all = [
        "@platforms//os:linux",
        ":dwarf_version_5",
    ],
)

# --------------------------------------
# disable_warnings_as_errors
# --------------------------------------

disable_warnings_as_errors(
    name = "disable_warnings_as_errors",
    build_setting_default = False,
)

config_setting(
    name = "warnings_as_errors_disabled",
    flag_values = {
        "//bazel/config:disable_warnings_as_errors": "True",
    },
)

config_setting(
    name = "warnings_as_errors_enabled",
    flag_values = {
        "//bazel/config:disable_warnings_as_errors": "False",
    },
)

selects.config_setting_group(
    name = "disable_warnings_as_errors_linux",
    match_all = [
        "@platforms//os:linux",
        ":warnings_as_errors_enabled",
    ],
)

selects.config_setting_group(
    name = "disable_warnings_as_errors_posix",
    match_all = [
        ":not_windows",
        ":warnings_as_errors_enabled",
    ],
)

selects.config_setting_group(
    name = "disable_warnings_as_errors_macos",
    match_all = [
        "@platforms//os:macos",
        ":warnings_as_errors_enabled",
    ],
)

selects.config_setting_group(
    name = "disable_warnings_as_errors_windows",
    match_all = [
        "@platforms//os:windows",
        ":warnings_as_errors_enabled",
    ],
)

# -----------
# ssl options
# -----------

ssl(
    name = "ssl",
    build_setting_default = True,
)

config_setting(
    name = "ssl_enabled",
    flag_values = {
        "//bazel/config:ssl": "True",
    },
)

config_setting(
    name = "ssl_disabled",
    flag_values = {
        "//bazel/config:ssl": "False",
    },
)

selects.config_setting_group(
    name = "ssl_enabled_windows",
    match_all = [
        "@platforms//os:windows",
        ":ssl_enabled",
    ],
)

selects.config_setting_group(
    name = "ssl_disabled_windows",
    match_all = [
        "@platforms//os:windows",
        ":ssl_enabled",
    ],
)

selects.config_setting_group(
    name = "ssl_enabled_macos",
    match_all = [
        "@platforms//os:macos",
        ":ssl_enabled",
    ],
)

selects.config_setting_group(
    name = "ssl_enabled_linux",
    match_all = [
        "@platforms//os:linux",
        ":ssl_enabled",
    ],
)

selects.config_setting_group(
    name = "ssl_disabled_linux",
    match_all = [
        "@platforms//os:linux",
        ":ssl_disabled",
    ],
)

# --------------------------------------
# thin_lto
# --------------------------------------

thin_lto(
    name = "thin_lto",
    build_setting_default = False,
)

config_setting(
    name = "thin_lto_enabled",
    flag_values = {
        "//bazel/config:thin_lto": "True",
    },
)

# --------------------------------------
# gdbserver options
# --------------------------------------

gcov(
    name = "gcov",
    build_setting_default = False,
)

config_setting(
    name = "gcov_enabled",
    flag_values = {
        "//bazel/config:gcov": "True",
    },
)

# --------------------------------------
# pgo_profile options
# --------------------------------------

pgo_profile(
    name = "pgo_profile",
    build_setting_default = False,
)

config_setting(
    name = "pgo_profile_enabled",
    flag_values = {
        "//bazel/config:pgo_profile": "True",
    },
)

bool_flag(
    name = "scons_query",
    build_setting_default = False,
)

config_setting(
    name = "scons_query_enabled",
    flag_values = {
        "//bazel/config:scons_query": "True",
    },
)

# --------------------------------------
# crypto options
# --------------------------------------

# Note: This intentionally matches regardless of SSL setting.
config_setting(
    name = "mongo_crypto_windows",
    constraint_values = ["@platforms//os:windows"],
)

# Note: This intentionally matches regardless of SSL setting.
config_setting(
    name = "mongo_crypto_apple",
    constraint_values = ["@platforms//os:macos"],
)

selects.config_setting_group(
    name = "mongo_crypto_openssl",
    match_all = [
        ":ssl_enabled_linux",
    ],
)

selects.config_setting_group(
    name = "mongo_crypto_tom",
    match_any = [
        ":ssl_disabled_linux",
    ],
)

# --------------------------------------
# ssl_provider options
# --------------------------------------

# TODO(SERVER-94377): The `mongo_crypto` setting refers to the old
# `MONGO_CRYPTO` variable in SCons. The `ssl_provider` usually coincides with
# that, but if ssl is disabled it'll get overridden to `none`. That is,
# regardless of operating system, you'll get `ssl_provider_none` here if ssl is
# disabled. We should figure out a more intuitive/robust solution to this.

[
    selects.config_setting_group(
        name = "ssl_provider_{}".format(mongo_crypto_value),
        match_all = [
            "mongo_crypto_{}".format(mongo_crypto_value),
            ":ssl_enabled",
        ],
    )
    for mongo_crypto_value in [
        "apple",
        "openssl",
        "windows",
    ]
]

selects.config_setting_group(
    name = "ssl_provider_none",
    match_all = [
        ":ssl_disabled",
    ],
)

# --------------------------------------
# symbol reordering options
# --------------------------------------

selects.config_setting_group(
    name = "symbol_ordering_file_enabled",
    match_all = [
        "@platforms//os:linux",
        ":opt_any",
        ":linker_lld",
    ],
)

# --------------------------------------
# developer dir
# --------------------------------------

developer_dir(
    name = "developer_dir",
    build_setting_default = "/Applications/Xcode.app",
)

# --------------------------------------
# js_engine options
# --------------------------------------

js_engine(
    name = "js_engine",
    build_setting_default = "mozjs",
)

config_setting(
    name = "js_engine_mozjs",
    flag_values = {
        "//bazel/config:js_engine": "mozjs",
    },
)

config_setting(
    name = "js_engine_none",
    flag_values = {
        "//bazel/config:js_engine": "none",
    },
)

# --------------------------------------
# enterprise_features options
# --------------------------------------

ALL_ENTERPRISE_FEATURES = [
    "audit",
    "encryptdb",
    "fcbis",
    "fips",
    "fle",
    "hot_backups",
    "inmemory",
    "kerberos",
    "ldap",
    "live_import",
    "magic_restore",
    "mongohouse",
    "queryable",
    "sasl",
    "streams",
]

[
    bool_flag(
        name = "enterprise_feature_" + feature,
        build_setting_default = False,
    )
    for feature in ALL_ENTERPRISE_FEATURES
]

[
    config_setting(
        name = "_enterprise_feature_" + feature + "_enabled",
        flag_values = {
            "//bazel/config:enterprise_feature_" + feature: "True",
        },
    )
    for feature in ALL_ENTERPRISE_FEATURES
]

[
    selects.config_setting_group(
        name = "_enterprise_feature_" + feature + "_and_enterprise_build_enabled",
        match_all = [
            ":_enterprise_feature_" + feature + "_enabled",
            ":build_enterprise_enabled",
        ],
    )
    for feature in ALL_ENTERPRISE_FEATURES
]

bool_flag(
    name = "enterprise_feature_all",
    build_setting_default = True,
)

config_setting(
    name = "_enterprise_feature_all_enabled",
    flag_values = {
        "//bazel/config:enterprise_feature_all": "True",
    },
)

selects.config_setting_group(
    name = "enterprise_feature_all_enabled",
    match_all = [
        ":_enterprise_feature_all_enabled",
        ":build_enterprise_enabled",
    ],
)

[
    selects.config_setting_group(
        name = "enterprise_feature_" + feature + "_enabled",
        match_any = [
            ":_enterprise_feature_" + feature + "_and_enterprise_build_enabled",
            ":enterprise_feature_all_enabled",
        ],
    )
    for feature in ALL_ENTERPRISE_FEATURES
]

selects.config_setting_group(
    name = "enterprise_feature_queryable_and_wiredtiger_enabled",
    match_all = [
        ":enterprise_feature_queryable_enabled",
        ":use_wiredtiger_enabled",
    ],
)

selects.config_setting_group(
    name = "enterprise_feature_fle_and_js_engine_enabled",
    match_all = [
        ":enterprise_feature_fle_enabled",
        ":js_engine_mozjs",
    ],
)

selects.config_setting_group(
    name = "enterprise_feature_streams_and_streams_build_enabled",
    match_all = [
        ":enterprise_feature_queryable_enabled",
        ":streams_release_build_required_setting",
    ],
)

selects.config_setting_group(
    name = "enterprise_feature_ldap_and_wiredtiger_enabled",
    match_all = [
        "//bazel/config:enterprise_feature_ldap_enabled",
        "//bazel/config:use_wiredtiger_enabled",
    ],
)

selects.config_setting_group(
    name = "enterprise_feature_audit_or_encryptdb_enabled",
    match_any = [
        ":enterprise_feature_audit_enabled",
        ":enterprise_feature_encryptdb_enabled",
    ],
)

# --------------------------------------
# server_js
# --------------------------------------

server_js(
    name = "server_js",
    build_setting_default = True,
)

config_setting(
    name = "server_js_enabled",
    flag_values = {
        "//bazel/config:server_js": "True",
    },
)

# --------------------------------------
# xray
# --------------------------------------

bool_flag(
    name = "xray",
    build_setting_default = False,
)

config_setting(
    name = "xray_enabled",
    flag_values = {
        "//bazel/config:xray": "True",
    },
)

# --------------------------------------
# use_sasl_client
# --------------------------------------

bool_flag(
    name = "use_sasl_client",
    build_setting_default = False,
)

config_setting(
    name = "use_sasl_client_enabled",
    flag_values = {
        "//bazel/config:use_sasl_client": "True",
    },
)

# --------------------------------------
# link_timeout_8min
# --------------------------------------

bool_flag(
    name = "link_timeout_8min",
    build_setting_default = False,
)

config_setting(
    name = "link_timeout_8min_enabled",
    flag_values = {
        "//bazel/config:link_timeout_8min": "True",
    },
)

# --------------------------------------
# fission
# --------------------------------------

config_setting(
    name = "fission_enabled",
    values = {
        "fission": "yes",
    },
)

config_setting(
    name = "linux_gcc_fission",
    constraint_values = [
        "@platforms//os:linux",
    ],
    flag_values = {
        "//bazel/config:compiler_type": "gcc",
    },
    values = {
        "fission": "yes",
    },
)

selects.config_setting_group(
    name = "linux_gcc_fission_x86_64",
    match_all = [
        "@platforms//cpu:x86_64",
        ":linux_gcc_fission",
    ],
)

selects.config_setting_group(
    name = "linux_gcc_fission_aarch64",
    match_all = [
        "@platforms//cpu:aarch64",
        ":linux_gcc_fission",
    ],
)
